"""WMS3D系统核心配置模块。

该模块使用pydantic-settings来管理应用程序的配置，支持：
1. 环境变量配置
2. 嵌套配置结构
3. 类型验证
4. 默认值设置

配置项通过环境变量进行覆盖，支持.env文件。
"""

from typing import Any

from pydantic import Field, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict


class DatabaseSettings(BaseSettings):
    """数据库配置。

    配置PostgreSQL数据库连接参数，包括异步和同步连接URL。
    """

    host: str = Field(default="localhost", description="数据库主机")
    port: int = Field(default=18030, description="数据库端口")
    username: str = Field(default="wms_user", description="数据库用户名")
    password: str = Field(default="wms_password", description="数据库密码")
    database: str = Field(default="wms3d", description="数据库名称")

    @property
    def url(self) -> str:
        """获取数据库URL（异步连接）。"""
        return f"postgresql+asyncpg://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}"

    @property
    def sync_url(self) -> str:
        """获取数据库URL（同步连接）。"""
        return (
            f"postgresql://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}"
        )

    model_config = SettingsConfigDict(env_prefix="DB_")


class RedisSettings(BaseSettings):
    """Redis配置。

    配置Redis连接参数，用于缓存和会话管理。
    """

    host: str = Field(default="localhost", description="Redis主机")
    port: int = Field(default=6379, description="Redis端口")
    password: str | None = Field(default=None, description="Redis密码")
    db: int = Field(default=0, description="Redis数据库编号")

    @property
    def url(self) -> str:
        """获取Redis URL。"""
        if self.password:
            return f"redis://:{self.password}@{self.host}:{self.port}/{self.db}"
        return f"redis://{self.host}:{self.port}/{self.db}"

    model_config = SettingsConfigDict(env_prefix="REDIS_")


class SensorSettings(BaseSettings):
    """传感器网关配置。

    配置传感器网关的网络参数和webhook URL。
    """

    host: str = Field(default="0.0.0.0", description="传感器网关主机")
    port: int = Field(default=8001, description="传感器网关端口")
    webhook_url: str = Field(
        default="http://localhost:8080/webhook/sensor-events", description="Dify/n8n的Webhook URL"
    )

    model_config = SettingsConfigDict(env_prefix="SENSOR_")


class TelemetrySettings(BaseSettings):
    """遥测配置。

    配置OpenTelemetry的相关参数。
    """

    otlp_endpoint: str = Field(default="localhost:4317", description="OTLP导出端点")
    otlp_insecure: bool = Field(default=True, description="是否使用不安全连接")

    model_config = SettingsConfigDict(env_prefix="TELEMETRY_")


class WMSSettings(BaseSettings):
    """WMS核心API配置。

    配置WMS核心API的网络参数和调试模式。
    """

    host: str = Field(default="0.0.0.0", description="WMS API主机")
    port: int = Field(default=8000, description="WMS API端口")
    debug: bool = Field(default=False, description="调试模式")

    model_config = SettingsConfigDict(env_prefix="WMS_")


class Settings(BaseSettings):
    """应用程序配置。

    整合所有子配置，提供应用程序的完整配置管理。
    """

    database: DatabaseSettings = DatabaseSettings()
    redis: RedisSettings = RedisSettings()
    sensor: SensorSettings = SensorSettings()
    wms: WMSSettings = WMSSettings()
    telemetry: TelemetrySettings = TelemetrySettings()

    # 仓库坐标系
    warehouse_bounds: dict[str, float] = Field(
        default={"x_min": 0, "x_max": 100, "y_min": 0, "y_max": 80, "z_min": 0, "z_max": 15},
        description="仓库坐标边界（米）",
    )

    # 事件处理
    event_timeout: int = Field(default=30, description="事件处理超时时间（秒）")

    model_config = SettingsConfigDict(env_file=".env", env_nested_delimiter="__", extra="ignore")


settings = Settings()
